﻿namespace InkType.ViewModel

open InkType.ViewModel.SavedTypefaces
open System
open System.Collections.Generic
open System.Collections.ObjectModel
open System.Text
open System.Text.RegularExpressions
open System.Windows
open System.Windows.Controls
open System.Windows.Ink
open System.Windows.Input
open System.Windows.Media


type GlyphListViewModel private (model : TypefaceModel, dc, characterBlocks, __) =
    inherit DependencyObject ()

    let glyphDictionary = Dictionary<_, _> ()
    do for glyph in model.Glyph do
        glyphDictionary.Add (glyph.CharCode, GlyphViewModel (glyph, dc))

    let blocks =
        let getGlyph charCode =
            glyphDictionary.TryGetValue charCode
            |> Option.ofByRefBool
            |> function
                | Some vm -> vm
                | None ->
                    GlyphViewModel (charCode, model, dc)
                    |>! fun vm -> glyphDictionary.Add (charCode, vm)

        characterBlocks
        |> Seq.map (fun (block : CharacterBlock) ->
            let glyphs =
                block.Characters
                |> Seq.map (fun c -> getGlyph (int c))
                |> Array.ofSeq
            CharacterBlockViewModel (block, glyphs))
        |> Array.ofSeq

    let recentBlocks = RecentItemsQueue<_> (12)

    static member val SelectedItemProperty =
        Dp.reg<CharacterBlockViewModel, GlyphListViewModel> "SelectedItem"
            (Dp.Meta (
                (null : CharacterBlockViewModel),
                fun x (oldval, _) -> if oldval <> null then oldval.OnExit ()))

    new (model, dc, characterBlocks) as x =
        GlyphListViewModel (model, dc, characterBlocks, ())
        then
            x.SelectedItem <- (x.Blocks : _ []).[0]

    member x.SelectedItem
        with get () = x.GetValue GlyphListViewModel.SelectedItemProperty :?> CharacterBlockViewModel
        and set (v : CharacterBlockViewModel) = x.SetValue (GlyphListViewModel.SelectedItemProperty, box v)

    member x.Blocks = blocks

    member x.DefinedGlyphs =
        glyphDictionary.Values
        |> Seq.filter (fun glyph -> glyph.StrokeCollection.Count > 0)

    member x.OnExit () =
        x.SelectedItem.OnExit ()

